﻿namespace LightCAD.Core.Filters
{
    [Flags]
    public enum FilterType
    {
        None = 0,
        Basic = 1,
        BlockRef = 2,
        BlockArrayRef = 4,
        GroupRef = 8,
        XrefRef = 16,
        ComponentSingleRef = 32,
        ComponentInstanceRef = 64,
        ComponentRef = ComponentSingleRef | ComponentInstanceRef,
        ByFunc = 128,
        ByLayers = 256,
        ByDrawingFrames = 512,
        ByProfiles = 1024,
        ALl = Basic | BlockRef | BlockArrayRef | GroupRef | XrefRef | ComponentRef | ByFunc | ByLayers | ByDrawingFrames | ByProfiles
    }

    public class FilterResult
    {
        public ReadonlyElementCollection Basics { get; internal set; }
        public ReadonlyElementCollection BlockRefs { get; internal set; }
        public ReadonlyElementCollection BlockArrayRefs { get; internal set; }
        public ReadonlyElementCollection GroupRefs { get; internal set; }
        public ReadonlyElementCollection XrefRefs { get; internal set; }
        public ReadonlyElementCollection ComSingleRefs { get; internal set; }
        public ReadonlyElementCollection ComInstanceRefs { get; internal set; }

        public ReadonlyElementCollection ByFuncs { get; internal set; }
        public Dictionary<Layer, ReadonlyElementCollection> ByLayers { get; internal set; }
        public Dictionary<DrawingFrame, ReadonlyElementCollection> ByDrawingFrames { get; internal set; }
        public Dictionary<SolidProfile, ReadonlyElementCollection> ByProfiles { get; internal set; }
    }
    public class ElementFilter
    {
        public ElementContainer Container { get; private set; }
        public ElementFilter(ElementContainer container)
        {
            this.Container = container;
        }
        public FilterResult Collect(FilterType filterType, Func<Element, Element> func = null)
        {
            var result = new FilterResult();
            InitFilterResult(filterType, result);
            foreach (var element in this.Container.Elements)
            {
                switch (element.Type)
                {
                    case ElementType.Line:
                    case ElementType.Arc:
                    case ElementType.Circle:
                    case ElementType.Ellipse:
                        if ((filterType & FilterType.Basic) == FilterType.Basic)
                        {
                            result.Basics.AddItem(element);
                        }
                        break;
                }
            }

            return result;
        }
        private void InitFilterResult(FilterType filterType, FilterResult result)
        {
            if ((filterType & FilterType.Basic) == FilterType.Basic)
                result.Basics = new ReadonlyElementCollection();
            if ((filterType & FilterType.BlockRef) == FilterType.BlockRef)
                result.BlockRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.BlockArrayRef) == FilterType.BlockArrayRef)
                result.BlockArrayRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.GroupRef) == FilterType.GroupRef)
                result.GroupRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.XrefRef) == FilterType.XrefRef)
                result.XrefRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.ComponentSingleRef) == FilterType.ComponentSingleRef)
                result.ComSingleRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.ComponentInstanceRef) == FilterType.ComponentInstanceRef)
                result.ComInstanceRefs = new ReadonlyElementCollection();
            if ((filterType & FilterType.ByFunc) == FilterType.ByFunc)
                result.ByFuncs = new ReadonlyElementCollection();
            if ((filterType & FilterType.ByLayers) == FilterType.ByLayers)
                result.ByLayers = new Dictionary<Layer, ReadonlyElementCollection>();
            if ((filterType & FilterType.ByDrawingFrames) == FilterType.ByDrawingFrames)
                result.ByDrawingFrames = new Dictionary<DrawingFrame, ReadonlyElementCollection>();
            if ((filterType & FilterType.ByProfiles) == FilterType.ByProfiles)
                result.ByProfiles = new Dictionary<SolidProfile, ReadonlyElementCollection>();
        }
    }
}
